home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / vidhrdw / battlera.c < prev    next >
C/C++ Source or Header  |  2000-05-03  |  13KB  |  491 lines

  1. /*******************************************************************************
  2.  
  3.     Battle Rangers - Bryan McPhail, mish@tendril.co.uk
  4.  
  5.     This file only implements necessary features - not all PC-Engine video
  6.     features are used in this game (no DMA for one).
  7.  
  8. *******************************************************************************/
  9.  
  10. #include "driver.h"
  11. #include "vidhrdw/generic.h"
  12. #include "cpu/h6280/h6280.h"
  13.  
  14. static int HuC6270_registers[20];
  15. static int VDC_register,vram_ptr;
  16. static unsigned char *HuC6270_vram,*tile_dirty,*sprite_dirty,*vram_dirty;
  17. static struct osd_bitmap *tile_bitmap,*front_bitmap;
  18.  
  19. static int current_scanline,next_update_first_line,inc_value;
  20. static int irq_enable,rcr_enable,sb_enable,bb_enable,bldwolf_vblank;
  21.  
  22. /******************************************************************************/
  23.  
  24. WRITE_HANDLER( battlera_palette_w )
  25. {
  26.     int r,g,b,pal_word;
  27.  
  28.     paletteram[offset]=data;
  29.     if (offset%2) offset-=1;
  30.  
  31.     pal_word=paletteram[offset] | (paletteram[offset+1]<<8);
  32.  
  33.     r = ((pal_word >> 3) & 7) << 5;
  34.     g = ((pal_word >> 6) & 7) << 5;
  35.     b = ((pal_word >> 0) & 7) << 5;
  36.     palette_change_color(offset/2, r, g, b);
  37. }
  38.  
  39. /******************************************************************************/
  40.  
  41. static void draw_sprites(struct osd_bitmap *bitmap,const struct rectangle *clip,int pri)
  42. {
  43.     int offs,my,mx,code,code2,fx,fy,cgy=0,cgx,colour,i;
  44.  
  45.     /* Draw sprites, starting at SATB, draw in _reverse_ order */
  46.     for (offs=(HuC6270_registers[19]<<1)+0x200-8; offs>=(HuC6270_registers[19]<<1); offs-=8)
  47.     {
  48.         if ((HuC6270_vram[offs+7]&0x80) && !pri) continue;
  49.         if (!(HuC6270_vram[offs+7]&0x80) && pri) continue;
  50.  
  51.         code=HuC6270_vram[offs+5] + (HuC6270_vram[offs+4]<<8);
  52.         code=code>>1;
  53.  
  54.         my=HuC6270_vram[offs+1] + (HuC6270_vram[offs+0]<<8);
  55.         mx=HuC6270_vram[offs+3] + (HuC6270_vram[offs+2]<<8);
  56.  
  57.         mx-=32;
  58.         my-=57;
  59.  
  60.         fx=HuC6270_vram[offs+6]&0x8;
  61.         fy=HuC6270_vram[offs+6]&0x80;
  62.         cgx=HuC6270_vram[offs+6]&1;
  63.         colour=HuC6270_vram[offs+7]&0xf;
  64.  
  65.         switch ((HuC6270_vram[offs+6]>>4)&3) {
  66.         case 0: cgy=1; break;
  67.         case 1: cgy=2; break;
  68.         case 2: cgy=0; break; /* Illegal */
  69.         case 3: cgy=4; break;
  70.         }
  71.  
  72.         if (cgx && cgy==2) code=code&0x3fc; /* Title screen */
  73.  
  74.         if (fx && cgx) {code2=code; code++;} /* Swap tile order on X flips */
  75.         else code2=code+1;
  76.  
  77.         for (i=0; i<cgy; i++) {
  78.             drawgfx(bitmap,Machine->gfx[1],
  79.                 code,
  80.                 colour,
  81.                 fx,fy,
  82.                 mx,my,
  83.                 clip,TRANSPARENCY_PEN,0);
  84.  
  85.             if (cgx)
  86.                 drawgfx(bitmap,Machine->gfx[1],
  87.                         code2,
  88.                         colour,
  89.                         fx,fy,
  90.                         mx+16,my,
  91.                         clip,TRANSPARENCY_PEN,0);
  92.             my+=16;
  93.             /* if (cgx) */ /* Different from console? */
  94.             code+=2;
  95.             code2+=2;
  96.             /*else code+=1; */ /* Different from console? */
  97.         }
  98.     }
  99.  
  100. }
  101.  
  102. static void screenrefresh(struct osd_bitmap *bitmap,const struct rectangle *clip)
  103. {
  104.     int offs,code,scrollx,scrolly,mx,my;
  105.  
  106.     /* Recalculate palette if needed */
  107.     palette_init_used_colors();
  108.  
  109.     for (offs=0; offs<256; offs++)
  110.         if (!(offs%16))
  111.             palette_used_colors[offs] = PALETTE_COLOR_TRANSPARENT;
  112.         else
  113.             palette_used_colors[offs] = PALETTE_COLOR_USED;
  114.  
  115.     for (offs=256; offs<512; offs++)
  116.             palette_used_colors[offs] = PALETTE_COLOR_USED;
  117.  
  118.     if (palette_recalc())
  119.         memset(vram_dirty,1,0x1000);
  120.  
  121.     /* Dynamically decode chars if dirty */
  122.     for (code = 0x0000;code < 0x1000;code++)
  123.         if (tile_dirty[code])
  124.             decodechar(Machine->gfx[0],code,HuC6270_vram,Machine->drv->gfxdecodeinfo[0].gfxlayout);
  125.  
  126.     /* Dynamically decode sprites if dirty */
  127.     for (code = 0x0000;code < 0x400;code++)
  128.         if (sprite_dirty[code])
  129.             decodechar(Machine->gfx[1],code,HuC6270_vram,Machine->drv->gfxdecodeinfo[1].gfxlayout);
  130.  
  131.     /* NB: If first 0x1000 byte is always tilemap, no need to decode the first batch of tiles/sprites */
  132.  
  133.     mx=-1;
  134.     my=0;
  135.     for (offs = 0x0000;offs < 0x2000;offs += 2)
  136.     {
  137.         mx++;
  138.         if (mx==64) {mx=0; my++;}
  139.         code=HuC6270_vram[offs+1] + ((HuC6270_vram[offs] & 0x0f) << 8);
  140.  
  141.         /* If this tile was changed OR tilemap was changed, redraw */
  142.         if (tile_dirty[code] || vram_dirty[offs/2]) {
  143.             vram_dirty[offs/2]=0;
  144.             drawgfx(tile_bitmap,Machine->gfx[0],
  145.                     code,
  146.                     HuC6270_vram[offs] >> 4,
  147.                     0,0,
  148.                     8*mx,8*my,
  149.                     0,TRANSPARENCY_NONE,0);
  150.             drawgfx(front_bitmap,Machine->gfx[2],
  151.                     0,
  152.                     0,
  153.                     0,0,
  154.                     8*mx,8*my,
  155.                     0,TRANSPARENCY_NONE,0);
  156.             drawgfx(front_bitmap,Machine->gfx[0],
  157.                     code,
  158.                     HuC6270_vram[offs] >> 4,
  159.                     0,0,
  160.                     8*mx,8*my,
  161.                     0,TRANSPARENCY_PENS,0x1);
  162.             }
  163.     }
  164.  
  165.     /* Nothing dirty after a screen refresh */
  166.     for (code = 0x0000;code < 0x1000;code++)
  167.         tile_dirty[code]=0;
  168.     for (code = 0x0000;code < 0x400;code++)
  169.         sprite_dirty[code]=0;
  170.  
  171.     /* Render bitmap */
  172.     scrollx=-HuC6270_registers[7];
  173.     scrolly=-HuC6270_registers[8]+clip->min_y-1;
  174.  
  175.     copyscrollbitmap(bitmap,tile_bitmap,1,&scrollx,1,&scrolly,clip,TRANSPARENCY_NONE,0);
  176.  
  177.     /* Todo:  Background enable (not used anyway) */
  178.  
  179.     /* Render low priority sprites, if enabled */
  180.     if (sb_enable) draw_sprites(bitmap,clip,0);
  181.  
  182.     /* Render background over sprites */
  183.     copyscrollbitmap(bitmap,front_bitmap,1,&scrollx,1,&scrolly,clip,TRANSPARENCY_PEN,palette_transparent_pen);
  184.  
  185.     /* Render high priority sprites, if enabled */
  186.     if (sb_enable) draw_sprites(bitmap,clip,1);
  187. }
  188.  
  189. /******************************************************************************/
  190.  
  191. READ_HANDLER( HuC6270_register_r )
  192. {
  193.     int rr;
  194.  
  195.     if ((current_scanline+56)==HuC6270_registers[6]) rr=1; else rr=0;
  196.  
  197.     return 0        /* CR flag */
  198.         | (0 << 1)    /* OR flag */
  199.         | (rr << 2)    /* RR flag */
  200.         | (0 << 3)    /* DS flag */
  201.         | (0 << 4)    /* DV flag */
  202.         | (bldwolf_vblank << 5)    /* VD flag (1 when vblank else 0) */
  203.         | (0 << 6)    /* BSY flag (1 when dma active, else 0) */
  204.         | (0 << 7);    /* Always zero */
  205. }
  206.  
  207. WRITE_HANDLER( HuC6270_register_w )
  208. {
  209.     switch (offset) {
  210.     case 0: /* Select data region */
  211.         VDC_register=data;
  212.         break;
  213.     case 1: /* Unused */
  214.         break;
  215.     }
  216. }
  217.  
  218. /******************************************************************************/
  219.  
  220. READ_HANDLER( HuC6270_data_r )
  221. {
  222.     int result;
  223.  
  224.     switch (offset) {
  225.         case 0: /* LSB */
  226.             return HuC6270_vram[(HuC6270_registers[1]<<1)|1];
  227.  
  228.         case 1:/* MSB */
  229.             result=HuC6270_vram[(HuC6270_registers[1]<<1)|0];
  230.             HuC6270_registers[1]=(HuC6270_registers[1]+inc_value)&0xffff;
  231.             return result;
  232.     }
  233.  
  234.     return 0;
  235. }
  236.  
  237. WRITE_HANDLER( HuC6270_data_w )
  238. {
  239.     switch (offset) {
  240.         case 0: /* LSB */
  241.             switch (VDC_register) {
  242.  
  243.             case 0: /* MAWR */
  244.                 HuC6270_registers[0]=(HuC6270_registers[0]&0xff00) | (data);
  245.                 return;
  246.  
  247.             case 1: /* MARR */
  248.                 HuC6270_registers[0]=(HuC6270_registers[1]&0xff00) | (data);
  249.                 return;
  250.  
  251.             case 2: /* VRAM */
  252.                 if (HuC6270_vram[(HuC6270_registers[0]<<1)|1]!=data) {
  253.                     HuC6270_vram[(HuC6270_registers[0]<<1)|1]=data;
  254.                     tile_dirty[HuC6270_registers[0]>>4]=1;
  255.                     sprite_dirty[HuC6270_registers[0]>>6]=1;
  256.                 }
  257.                 if (HuC6270_registers[0]<0x1000) vram_dirty[HuC6270_registers[0]]=1;
  258.                 return;
  259.  
  260.             case 3: break; /* Unused */
  261.             case 4: break; /* Unused */
  262.  
  263.             case 5: /* CR - Control register */
  264.                 /* Bits 0,1 unknown */
  265.                 rcr_enable=data&0x4; /* Raster interrupt enable */
  266.                 irq_enable=data&0x8; /* VBL interrupt enable */
  267.                 /* Bits 4,5 unknown (EX) */
  268.                 sb_enable=data&0x40; /* Sprites enable */
  269.                 bb_enable=data&0x80; /* Background enable */
  270.                 return;
  271.  
  272.             case 6: /* RCR - Raster counter register */
  273.                 HuC6270_registers[6]=(HuC6270_registers[6]&0xff00) | (data);
  274.                 return;
  275.  
  276.             case 7: /* BXR - X scroll */
  277.                 HuC6270_registers[7]=(HuC6270_registers[7]&0xff00) | (data);
  278.                 return;
  279.  
  280.             case 8: /* BYR - Y scroll */
  281.                 HuC6270_registers[8]=(HuC6270_registers[8]&0xff00) | (data);
  282.                 return;
  283.  
  284.             case 15: /* DMA */
  285.             case 16:
  286.             case 17:
  287.             case 18:
  288.                 logerror("%04x: dma 2 %02x\n",cpu_get_pc(),data);
  289.                 break;
  290.  
  291.             case 19: /* SATB */
  292.                 HuC6270_registers[19]=(HuC6270_registers[19]&0xff00) | (data);
  293.                 return;
  294.  
  295.             }
  296.             break;
  297.  
  298.         /*********************************************/
  299.  
  300.         case 1: /* MSB (Autoincrement on this write) */
  301.             switch (VDC_register) {
  302.  
  303.             case 0: /* MAWR - Memory Address Write Register */
  304.                 HuC6270_registers[0]=(HuC6270_registers[0]&0xff) | (data<<8);
  305.                 return;
  306.  
  307.             case 1: /* MARR */
  308.                 HuC6270_registers[1]=(HuC6270_registers[1]&0xff) | (data<<8);
  309.                 return;
  310.  
  311.             case 2: /* VWR - VRAM */
  312.                 if (HuC6270_vram[(HuC6270_registers[0]<<1)|0]!=data) {
  313.                     HuC6270_vram[(HuC6270_registers[0]<<1)|0]=data;
  314.                     tile_dirty[HuC6270_registers[0]>>4]=1;
  315.                     sprite_dirty[HuC6270_registers[0]>>6]=1;
  316.                     if (HuC6270_registers[0]<0x1000) vram_dirty[HuC6270_registers[0]]=1;
  317.                 }
  318.                 HuC6270_registers[0]+=inc_value;
  319.                 HuC6270_registers[0]=HuC6270_registers[0]&0xffff;
  320.                 return;
  321.  
  322.             case 5: /* CR */
  323.                 /* IW - Auto-increment values */
  324.                 switch ((data>>3)&3) {
  325.                     case 0: inc_value=1; break;
  326.                     case 1: inc_value=32;break;
  327.                     case 2: inc_value=64; break;
  328.                     case 3: inc_value=128; break;
  329.                 }
  330.  
  331.                 /* DR, TE unknown */
  332.                 return;
  333.  
  334.             case 6: /* RCR - Raster counter register */
  335.                 HuC6270_registers[6]=(HuC6270_registers[6]&0xff) | (data<<8);
  336.                 return;
  337.  
  338.             case 7: /* BXR - X scroll */
  339.                 HuC6270_registers[7]=(HuC6270_registers[7]&0xff) | (data<<8);
  340.                         return;
  341.  
  342.             case 8: /* BYR - Y scroll */
  343.                 HuC6270_registers[8]=(HuC6270_registers[8]&0xff) | (data<<8);
  344.                 return;
  345.  
  346.             case 15: /* DMA */
  347.             case 16:
  348.             case 17:
  349.             case 18:
  350.                 logerror("%04x: dma 2 %02x\n",cpu_get_pc(),data);
  351.                 break;
  352.  
  353.             case 19: /* SATB - Sprites */
  354.                 HuC6270_registers[19]=(HuC6270_registers[19]&0xff) | (data<<8);
  355.                 return;
  356.             }
  357.             break;
  358.     }
  359.     logerror("%04x: unknown write to  VDC_register %02x (%02x) at %02x\n",cpu_get_pc(),VDC_register,data,offset);
  360. }
  361.  
  362. /******************************************************************************/
  363.  
  364. void battlera_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
  365. {
  366.     /* Nothing */
  367. }
  368.  
  369. static void partial_refresh(struct osd_bitmap *bitmap,int current_line)
  370. {
  371.     struct rectangle clip;
  372.  
  373.     clip.min_x = Machine->drv->visible_area.min_x;
  374.     clip.max_x = Machine->drv->visible_area.max_x;
  375.     clip.min_y = next_update_first_line;
  376.     clip.max_y = current_line;
  377.     if (clip.min_y < Machine->drv->visible_area.min_y)
  378.         clip.min_y = Machine->drv->visible_area.min_y;
  379.     if (clip.max_y > Machine->drv->visible_area.max_y)
  380.         clip.max_y = Machine->drv->visible_area.max_y;
  381.  
  382.     if (clip.max_y >= clip.min_y)
  383.     {
  384.         screenrefresh(bitmap,&clip);
  385.     }
  386.  
  387.     next_update_first_line = current_line + 1;
  388. }
  389.  
  390. void battlera_vh_raster_partial_refresh(struct osd_bitmap *bitmap,int start_line,int end_line)
  391. {
  392.     struct rectangle clip;
  393.  
  394.     clip.min_x = Machine->drv->visible_area.min_x;
  395.     clip.max_x = Machine->drv->visible_area.max_x;
  396.     clip.min_y = start_line;
  397.     clip.max_y = end_line;
  398.     if (clip.min_y < Machine->drv->visible_area.min_y)
  399.         clip.min_y = Machine->drv->visible_area.min_y;
  400.     if (clip.max_y > Machine->drv->visible_area.max_y)
  401.         clip.max_y = Machine->drv->visible_area.max_y;
  402.  
  403.     if (clip.max_y > clip.min_y)
  404.     {
  405.         screenrefresh(bitmap,&clip);
  406.     }
  407. }
  408.  
  409. /******************************************************************************/
  410.  
  411. int battlera_interrupt(void)
  412. {
  413.     static int last_line=0;
  414.  
  415.     current_scanline=255-cpu_getiloops(); /* 8 lines clipped at top */
  416.  
  417.     /* If raster interrupt occurs, refresh screen _up_ to this point */
  418.     if (rcr_enable && (current_scanline+56)==HuC6270_registers[6]) {
  419.         battlera_vh_raster_partial_refresh(Machine->scrbitmap,last_line,current_scanline);
  420.         last_line=current_scanline;
  421.         return H6280_INT_IRQ1; /* RCR interrupt */
  422.     }
  423.  
  424.     /* Start of vblank */
  425.     if (current_scanline==240) {
  426.         bldwolf_vblank=1;
  427.         battlera_vh_raster_partial_refresh(Machine->scrbitmap,last_line,240);
  428.         if (irq_enable)
  429.             return H6280_INT_IRQ1; /* VBL */
  430.     }
  431.  
  432.     /* End of vblank */
  433.     if (current_scanline==254) {
  434.         bldwolf_vblank=0;
  435.         last_line=0;
  436.     }
  437.  
  438.     return 0;
  439. }
  440.  
  441. /******************************************************************************/
  442.  
  443. READ_HANDLER( HuC6270_debug_r )
  444. {
  445.     return HuC6270_vram[offset];
  446. }
  447.  
  448. WRITE_HANDLER( HuC6270_debug_w )
  449. {
  450.     HuC6270_vram[offset]=data;
  451. }
  452.  
  453. /******************************************************************************/
  454.  
  455. void battlera_vh_stop (void)
  456. {
  457.     free(tile_dirty);
  458.     free(HuC6270_vram);
  459.     free(sprite_dirty);
  460.     free(vram_dirty);
  461.  
  462.     osd_free_bitmap (tile_bitmap);
  463.     osd_free_bitmap (front_bitmap);
  464. }
  465.  
  466. int battlera_vh_start (void)
  467. {
  468.     HuC6270_vram=malloc(0x20000);
  469.     tile_dirty=malloc(0x1000);
  470.     sprite_dirty=malloc(0x400);
  471.     vram_dirty=malloc(0x1000);
  472.  
  473.     memset(HuC6270_vram,0,0x20000);
  474.     memset(tile_dirty,1,0x1000);
  475.     memset(sprite_dirty,1,0x400);
  476.     memset(vram_dirty,1,0x1000);
  477.  
  478.     tile_bitmap=osd_create_bitmap(512,512);
  479.     front_bitmap=osd_create_bitmap(512,512);
  480.  
  481.     if (!tile_bitmap || !front_bitmap || !tile_dirty || !HuC6270_vram || !sprite_dirty || !vram_dirty)
  482.         return 1;
  483.  
  484.     vram_ptr=0;
  485.     inc_value=1;
  486.     current_scanline=0;
  487.     irq_enable=rcr_enable=sb_enable=bb_enable=0;
  488.  
  489.     return 0;
  490. }
  491.